﻿/*
 * Created by SharpDevelop.
 * User: Intel
 * Date: 10.12.2014
 * Time: 13:58
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;

using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Linq;
using System.Windows.Forms.VisualStyles;
namespace Region.Utils
{
  /// <summary>
  /// Description of TableView.
  /// </summary>
  public partial class TableView : UserControl
  {    
    public class RowCollection
    {
      public class Row
      {
        Int32 m_RowID;
        public Int32 RowID{get{return m_RowID;}}        
        readonly RowCollection m_rowCollection;
        protected internal Button m_Button;
        protected internal RowStyle m_RowStyle;
        public float Height{get{return m_RowStyle.Height;}set{m_RowStyle.Height=value;change();}}        
        
        public RowCollection rowCollection{get{return m_rowCollection;}}
        public CellCollection.Cell getCell(ColumnCollection.Column col)
        {
          return m_rowCollection.m_tableView.Cells.getCell(col,this);
        }
        public CellCollection.Cell getCell(String colName)
        {
          var col = m_rowCollection.m_tableView.Columns.getColumnFromName(colName);
          if (col==null) 
            return null;
          return m_rowCollection.m_tableView.Cells.getCell(col,this);
        }

        public Row(RowCollection rowCollection)
        {          
          m_rowCollection = rowCollection;
          m_RowID = m_rowCollection.newRowID();
          m_RowStyle = new RowStyle(SizeType.Absolute,RowDefaultSize);
        }
        void change()
        {
          if (m_rowCollection!=null)
            m_rowCollection.changeRow(this);
        }
      }
      Dictionary<Int32,Row> m_RowsID;
      List<Row> m_Rows;      
      Int32 m_RowID=0;
      
      public Int32 Count{get{return m_Rows.Count;}}
      public Row this[int index]{get{return m_Rows[index];}set{m_Rows[index]=value;}}      
      readonly TableView m_tableView;
      public TableView tableView{get{return m_tableView;}}
      public RowCollection(TableView tableView)
      {
        m_tableView = tableView;
        m_Rows = new List<Row>();
        m_RowsID = new Dictionary<Int32, Row>();
      }
      Int32 newRowID(){return m_RowID++;}        
      public Row newRow()
      {
        var row = new Row(this);
        m_Rows.Add(row);
        m_RowsID.Add(row.RowID,row);
        changeRow(row);
        return row;
      }
      public Row getRowFromID(Int32 RowID)
      {
        if (m_RowsID.ContainsKey(RowID)) 
          return m_RowsID[RowID];
        return null;
      }
      protected internal void changeRow(Row row)
      {
        if(m_tableView!=null)
          m_tableView.change();
      }
      public List<Row> ToList()
      {
        return new List<Row>(m_Rows);
      }
      public void Clear()
      {
        m_Rows.Clear();
        m_RowsID.Clear();
      }
    }
    public class ColumnCollection 
    {
      public class Column
      {
        Int32 m_ColumnID;
        public Int32 ColumnID{get{return m_ColumnID;}}
        ColumnCollection m_columnCollection;
        public ColumnCollection columnCollection{get{return m_columnCollection;}}
        String m_Name;
        public String Name{
          get
          {
            return m_Name;
          }
          set
          {
            if (m_Name!="")
              m_columnCollection.m_ColumnsName.Remove(m_Name);
            m_Name = value;
            if (m_Name!="")
              m_columnCollection.m_ColumnsName[m_Name] = this;
          }
        }
        Int32 m_Position = 0;
        public Int32 Position{get{return m_Position;}set{m_Position=value;change();}}        
        public String DelegateType = null;
        Boolean m_Visible=true;
        public Boolean Visible{get{return m_Visible;}set{m_Visible=value;change();}}
        protected internal Button m_Button;
        protected internal ColumnStyle m_ColumnStyle;
        public float Width{get{return m_ColumnStyle.Width;}set{m_ColumnStyle.Width=value;change();}}        
        public Column(ColumnCollection columnCollection, String Name = "", String Caption="Column",Int32 Position = Int32.MaxValue)
        {
          m_columnCollection = columnCollection;
          m_ColumnID = m_columnCollection.newColumnID();
          m_Name = Name;
          m_Caption = Caption;
          m_ColumnStyle = new ColumnStyle(SizeType.Absolute,ColDefaultSize);
          this.Position = Position;
        }
        //protected internal ColHeaderCollection collection = null;
        string m_Caption="";
        public String Caption{get{return m_Caption;}set{m_Caption=value; change();}}
        void change()
        {
          if (m_columnCollection!=null)
            m_columnCollection.changeColumn(this);
        }
      }      
      Dictionary<Int32,Column> m_ColumnsID;
      Dictionary<String,Column> m_ColumnsName;
      List<Column> m_Columns;      
      Int32 m_ColumnID=0;
      Int32 newColumnID(){return m_ColumnID++;}
      public Column getColumnFromID(Int32 ColumnID)
      {
        if (m_ColumnsID.ContainsKey(ColumnID)) 
          return m_ColumnsID[ColumnID];
        return null;
      }
      public Column getColumnFromName(String Name)
      {
        if (m_ColumnsName.ContainsKey(Name)) 
          return m_ColumnsName[Name];
        return null;
      }
      public Boolean isColumn(Column Column)
      {
        if (Column.columnCollection!=this) return false;
        if (getColumnFromID(Column.ColumnID)!=Column) return false;
        return true;
      }
      public Column newColumn()
      {
        var col = new Column(this);
        m_Columns.Add(col);
        m_ColumnsID.Add(col.ColumnID,col);
        changeColumn(col);
        return col;
      }      
      TableView m_tableView;
      public ColumnCollection(TableView tableView)
      {        
        m_tableView = tableView; 
        m_Columns = new List<Column>();
        m_ColumnsID = new Dictionary<Int32, Column>();
        m_ColumnsName = new Dictionary<String, Column>();
      }
      protected internal void changeColumn(Column col)
      {
        if(m_tableView!=null)
          m_tableView.change();
      }
      public List<Column> ToList()
      {
        return new List<Column>(m_Columns);
      }
      public ColumnCollection.Column Add(String Name, String Caption="Column",Int32 Position = Int32.MaxValue)
      {
        var header = newColumn();
        header.Caption = Caption;
        header.Position = Position;
        header.Name = Name;
        return header;
      }
    }   
    public class CellCollection
    {
      public class Cell      
      {
        CellCollection m_cellCollection;
        RowCollection.Row m_Row;
        ColumnCollection.Column m_Column;
        Int32 m_CellID;
        public Int32 CellID{get{return m_CellID;}}
        public RowCollection.Row Row{get{return m_Row;}}
        public ColumnCollection.Column Column{get{return m_Column;}}
        
        Object m_Value = null;
        public Object Value{get{return m_Value;}set{m_Value = value;}}
        String m_DelegateType = null;
        public String DelegateType{get{return (m_DelegateType==null)?m_Column.DelegateType:m_DelegateType;}set{m_DelegateType = value;}}
                
        Boolean m_ReadOnly = false;
        public Boolean ReadOnly{get{return m_ReadOnly;}set{m_ReadOnly = value;}}
        protected internal Delegator m_Delegator;
        protected internal Control m_Editor;
        protected internal Cell(CellCollection cellCollection, RowCollection.Row Row, ColumnCollection.Column Column)        
        {
          m_cellCollection = cellCollection;
          m_Row = Row;
          m_Column = Column;
          m_CellID = cellCollection.newCellID();
          m_cellCollection.m_cellsID[m_CellID] = this;
          m_cellCollection.m_cells.Add(this);
        }
      }
      //[Col][Row][Type]
      Dictionary<Int32,Dictionary<Int32,Cell>> cellsRowColumn;
      Dictionary<Int32,Cell> m_cellsID;
      List<Cell> m_cells;
      
      TableView m_tableView;
      Int32 m_CellID=0;
      Int32 newCellID(){return m_CellID++;}    
      public void Clear()
      {
        m_cells = new List<Cell>();
        m_cellsID = new Dictionary<Int32, Cell>();
        cellsRowColumn = new Dictionary<Int32,Dictionary<Int32,Cell>>();
      }
      void changeHeader(ColumnCollection.Column col)
      {
        if (m_tableView.Columns == col.columnCollection)
          cellsRowColumn.Remove(col.ColumnID);
      }
      public CellCollection(TableView tableView)        
      {
        m_tableView = tableView;        
        m_tableView.onChangeHeader += changeHeader;
        Clear();
      }    
      public Cell getCell(ColumnCollection.Column col,RowCollection.Row row)
      {
        if (row.rowCollection!=m_tableView.Rows || col.columnCollection!=m_tableView.Columns)
          throw new Exception("Строка или столбец непринадлежат этой таблице");
        Int32 RowID = row.RowID;
        Int32 ColumnID = col.ColumnID;
        if (!cellsRowColumn.ContainsKey(ColumnID))
          cellsRowColumn[ColumnID] = new Dictionary<Int32, Cell>();
        if (!cellsRowColumn[ColumnID].ContainsKey(RowID))
          cellsRowColumn[ColumnID][RowID] = new Cell(this,row,col);        
        return cellsRowColumn[ColumnID][RowID];
      }
      public List<Cell> ToList()
      {
        return new List<Cell>(m_cells);
      }
    }
    public class Delegator
    {
      public virtual Control create(CellCollection.Cell cell){return null;}
      public virtual bool set(Control editor, CellCollection.Cell cell){return false;}
      public virtual Object get(Control editor, CellCollection.Cell cell){return null;}
    }
    class StandardDelegator:Delegator
    {
      Dictionary<Control,CellCollection.Cell> cells = new Dictionary<Control,CellCollection.Cell>();
      Boolean TextBox_TextChanged_cancel = false;
      void TextBox_TextChanged(object sender, EventArgs e)
      {
        if (TextBox_TextChanged_cancel) return;
      }
      public override Control create(CellCollection.Cell cell)
      {

        if (cell.DelegateType=="TextBox")
        {
          var contol = new TextBox();
          contol.BorderStyle = BorderStyle.None;
          contol.Margin = new Padding(0);
          contol.TextChanged += TextBox_TextChanged;
          return contol;
        }
        else if (cell.DelegateType=="CheckBox")
        {
          var contol = new CheckBox();
          //contol.BorderStyle = BorderStyle.None;
          contol.Margin = new Padding(0);
          contol.TextChanged += TextBox_TextChanged;
          return contol;
        }
        else
        {
          var contol = new Label();
          return contol;
        }
      }
      public override bool set(Control editor, CellCollection.Cell cell)
      {
        
        if (cell.DelegateType=="TextBox" && editor is TextBox)
        {
          var textBox = editor as TextBox;
          String Value = cell.Value==null?"null":cell.Value.ToString();
          Boolean ReadOnly = cell.ReadOnly;
          if (textBox.Text != Value)
          {
            TextBox_TextChanged_cancel = true;
            textBox.Text = Value;
            TextBox_TextChanged_cancel = false;
          }
          if (textBox.ReadOnly != ReadOnly)
            textBox.ReadOnly = ReadOnly;
          return true;
        }
        else if (cell.DelegateType=="CheckBox" && editor is CheckBox)
        {
          var checkBox = editor as CheckBox;
          CheckState Value =  cell.Value==null?CheckState.Indeterminate:(((Boolean)cell.Value)?CheckState.Checked:CheckState.Unchecked);
          Boolean enable = !cell.ReadOnly;
          if (checkBox.CheckState != Value)
          {
            TextBox_TextChanged_cancel = true;
            checkBox.CheckState = Value;
            TextBox_TextChanged_cancel = false;
          }
          if (checkBox.Enabled != enable)
            checkBox.Enabled = enable;
          return true;
        }
        else if (editor as  Label != null)
        {
          var label = editor as Label;      
          String Value = cell.Value.ToString(); 
          Boolean ReadOnly = cell.ReadOnly;        
          if (label.Text != Value)          
            label.Text = Value;
          return true;
        }
        return false;
      }
      public override Object get(Control editor, CellCollection.Cell cell)
      {
        if (cell.DelegateType=="TextBox" && editor is TextBox)
        {
          var textBox = editor as TextBox;
          return textBox.Text;
        }
        else if (cell.DelegateType=="CheckBox" && editor is CheckBox)
        {
          var checkBox = editor as CheckBox;
          switch(checkBox.CheckState)
          {
              case CheckState.Checked:return true;
              case CheckState.Unchecked:return false;
              case CheckState.Indeterminate:return null;
          }          
        }
        else if (editor as  Label != null)
        {
          var label = editor as Label;      
          return label.Text;
        }      
        return null;
      }
    }
    public class GroupCollection
    {
      public class GroupeInfo
      {
        Control m_Control = null;
        String m_Caption = null;
        readonly IEnumerable<Object> m_Key;
        protected internal RowStyle m_RowStyle;
        
        public float Height{get{return m_RowStyle.Height;}set{m_RowStyle.Height=value;change();}}
        public IEnumerable<Object> Key{get{return m_Key;}}
        public String Caption{
          get
          {
            if (m_Caption==null)
            {              
              m_Caption = String.Join(" ",(from k in m_Key select k.ToString()).ToArray());
            }
            return m_Caption;
          }
        }
        public Control Control{
          get
          {
            if (m_Control==null)
            {
              var label = new Label();
              label.Text = Caption;
              label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;              
              m_Control = label;
            }
            return m_Control;
          }
        }
        public GroupeInfo(IEnumerable<Object> Key)
        {
          m_Key = Key;
          m_RowStyle = new RowStyle(SizeType.Absolute,RowDefaultSize);
        }
        void change()
        {
        /*  if (m_rowCollection!=null)
            m_rowCollection.changeRow(this);*/
        }
      }      
      Dictionary<IEnumerable<Object>,GroupeInfo> r = new Dictionary<IEnumerable<Object>,GroupeInfo>(new IEnumerableComparer());
      public GroupeInfo getInfo(IEnumerable<Object> Key)
      {
        if (!r.ContainsKey(Key))
          r[Key] = new GroupeInfo(Key);
        return r[Key];
      }
      List<ColumnCollection.Column> m_Group = new List<ColumnCollection.Column>();
      public List<ColumnCollection.Column> Group{get{return new List<ColumnCollection.Column>(m_Group);}}
      readonly TableView m_tableView;
      public TableView tableView{get{return m_tableView;}}
      public GroupCollection(TableView tableView)
      {
        m_tableView = tableView;
        
      }
      public void Clear()
      {
        m_Group = new List<ColumnCollection.Column>();
      }
      public void Add(params  ColumnCollection.Column[] Group)
      {
        m_Group.AddRange(from gr in Group where m_tableView.Columns.isColumn(gr) select gr);
      } 
            
    }
    Boolean m_Show = false;
    Boolean m_showColHeader = true;
    Boolean m_showRowHeader = false;
    public Boolean showColHeader{get{return m_showColHeader;}set{m_showColHeader=value;showAll();}}
    public Boolean showRowHeader{get{return m_showRowHeader;}set{m_showRowHeader=value;showAll();}}
    const Int32 RowDefaultSize = 15;
    const Int32 RowHeaderDefaultSize = 20;
    const Int32 ColDefaultSize = 75;
    const Int32 ColHeaderDefaultSize = 25;
    readonly public RowCollection Rows;
    readonly public ColumnCollection Columns;
    readonly public GroupCollection Group;
    delegate void changeHeaderDeleate(ColumnCollection.Column col);    
    List<Delegator> DelegatorList;
    Control createDeleate(CellCollection.Cell cell)
    {
      for(Int32 i=DelegatorList.Count-1;i>=0;i--)
      {
        Control c = DelegatorList[i].create(cell);
        if (c!=null) 
        {
          cell.m_Delegator = DelegatorList[i];
          return c;
        }
      }
      return null;
    }
    bool setDeleate(Control editor,CellCollection.Cell cell)
    {
      if (cell.m_Delegator!=null)      
        return cell.m_Delegator.set(editor,cell);
      for(Int32 i=DelegatorList.Count-1;i>=0;i--)
        if (DelegatorList[i].set(editor,cell))         
          return true;        
      return false;
    }
    Object getDeleate(Control editor,CellCollection.Cell cell)
    {
      if (cell.m_Delegator!=null)      
        return cell.m_Delegator.get(editor,cell);
      for(Int32 i=DelegatorList.Count-1;i>=0;i--)
      {
        Object value = DelegatorList[i].get(editor,cell);
        if (value!=null)         
          return value;
      }
      return null;
    }
    event changeHeaderDeleate onChangeHeader;
    void change()
    {      
      showAll();
    }
    void showCells(IEnumerable<ColumnCollection.Column> listHeader,IEnumerable<RowCollection.Row> listRow)
    {
      tableLayoutPanel1.Visible = false;
      Int32 colN=0;
      foreach(ColumnCollection.Column col in listHeader)
      {
        Int32 RowN=0;
        foreach(RowCollection.Row row in listRow)                
        {
           CellCollection.Cell cell = Cells.getCell(col,row);
           if (cell.m_Editor==null)
           {
             cell.m_Editor = createDeleate(cell);
             setDeleate(cell.m_Editor,cell);
           }
           cell.m_Editor.Parent = null;
           cell.m_Editor.Dock = DockStyle.Fill;
           tableLayoutPanel1.Controls.Add(cell.m_Editor,1+colN ,1+RowN);
           RowN++;
        }
        colN++;
      }
      tableLayoutPanel1.Visible = true;
    }
    void setCells()
    {
      List<CellCollection.Cell> cells = Cells.ToList();
      foreach(CellCollection.Cell cell in Cells.ToList())        
      {
          setDeleate(cell.m_Editor,cell);
      }
    }
    void getCells()
    {
      List<CellCollection.Cell> cells = Cells.ToList();
      foreach(CellCollection.Cell cell in Cells.ToList())        
      {
          cell.Value = getDeleate(cell.m_Editor,cell);
      }
    }
    RowStyle FirstRowStyle = null;
    ColumnStyle FirstColumnStyle = null;
    void showHeader(IEnumerable<ColumnCollection.Column> listHeader,IEnumerable<RowCollection.Row> listRow)
    {            
      Int32 ColHeader =1; //m_showColHeader?1:0;
      Int32 RowHeader =1; //m_showRowHeader?1:0;
      float W=0;
      float H=0;
      tableLayoutPanel1.ColumnCount = RowHeader + listHeader.Count()+1;
      tableLayoutPanel1.RowCount = ColHeader + listRow.Count()+1;
      
      tableLayoutPanel1.RowStyles.Clear();
      tableLayoutPanel1.ColumnStyles.Clear();
      if (FirstRowStyle==null)
        FirstRowStyle = new RowStyle(SizeType.Absolute, RowHeaderDefaultSize);
      FirstRowStyle.Height = m_showColHeader?RowHeaderDefaultSize:0;
      if (FirstColumnStyle==null)
        FirstColumnStyle = new ColumnStyle(SizeType.Absolute, ColHeaderDefaultSize);
      FirstColumnStyle.Width = m_showRowHeader?ColHeaderDefaultSize:0;

      tableLayoutPanel1.RowStyles.Add(FirstRowStyle);
      tableLayoutPanel1.ColumnStyles.Add(FirstColumnStyle);
      W += FirstColumnStyle.Width;
      H += FirstRowStyle.Height;
      Int32 colN=0;
      foreach(ColumnCollection.Column h in listHeader)      
      {        
        tableLayoutPanel1.ColumnStyles.Add(h.m_ColumnStyle);
        W += h.Width;
        if (h.m_Button==null)
        {
          h.m_Button = new Button();          
          h.m_Button.Dock = DockStyle.Fill;
          h.m_Button.Margin = new Padding(0);
          h.m_Button.FlatStyle = FlatStyle.Popup;
        }
        h.m_Button.Parent = null;
        tableLayoutPanel1.Controls.Add(h.m_Button, RowHeader+colN, 0);
        h.m_Button.Text = h.Caption;       
        colN++;
      }
      Int32 rowN=0;
      foreach(RowCollection.Row h in listRow)      
      {
        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute,RowDefaultSize));                
        H += h.Height;
        if (h.m_Button==null)
        {
          h.m_Button = new Button();          
          h.m_Button.Dock = DockStyle.Fill;
          h.m_Button.Margin = new Padding(0);
          h.m_Button.FlatStyle = FlatStyle.Popup;
        }
        h.m_Button.Parent = null;
        tableLayoutPanel1.Controls.Add(h.m_Button, 0, ColHeader+rowN);
        h.m_Button.Text = (rowN+1).ToString();
        rowN++;
      }
        
      tableLayoutPanel1.Width = (Int32)W;
      tableLayoutPanel1.Height = (Int32)H;
    }  
    
    void showAll()
    {
      if (m_Show==false) return;
      IEnumerable<ColumnCollection.Column> qCol = from ch in Columns.ToList() select ch;
      IEnumerable<RowCollection.Row> qRow = from ch in Rows.ToList() select ch;      
      IEnumerable<IGrouping<IEnumerable<Object>,RowCollection.Row>> qGroup = qRow.GroupBy(row=>from gr in Group.Group select row.getCell(gr).Value,new IEnumerableComparer());
      // Сортировка столбцов
      qCol  = from col in qCol where col.Visible orderby col.Position ascending,col.Caption ascending, col.Name ascending select col;
      
      // Сортировка по порядку заполнения
      qRow  = from row in qRow orderby row.RowID ascending select row;
      List<ColumnCollection.Column> listHeader = qCol.ToList();
      List<RowCollection.Row> listRow = qRow.ToList();
      
      tableLayoutPanel1.ColumnStyles.Clear();
      tableLayoutPanel1.RowStyles.Clear();
      if (FirstRowStyle==null)
        FirstRowStyle = new RowStyle(SizeType.Absolute, RowHeaderDefaultSize);
      if (FirstColumnStyle==null)
        FirstColumnStyle = new ColumnStyle(SizeType.Absolute, ColHeaderDefaultSize);

      //Вывести наименование столбцов
      //tableLayoutPanel1.ColumnCount = 1 + listHeader.Count() + 1;
      FirstRowStyle.Height = m_showColHeader?RowHeaderDefaultSize:0; //  Скрывает строку заголовка задавая ей нулевую высоту 
      tableLayoutPanel1.RowStyles.Add(FirstRowStyle);
      

      //Вывести наименование строк
      FirstColumnStyle.Width = m_showRowHeader?ColHeaderDefaultSize:0;
      tableLayoutPanel1.ColumnStyles.Add(FirstColumnStyle);
      float W = FirstColumnStyle.Width;
      float H = FirstRowStyle.Height;
      //var collection = new TableLayoutControlCollection(tableLayoutPanel1);
      Int32 ColN=0;
      Int32 RowN=0;
      foreach(ColumnCollection.Column h in listHeader)      
      {        
        tableLayoutPanel1.ColumnStyles.Add(h.m_ColumnStyle);
        W += h.Width;
        if (h.m_Button==null)
        {
          h.m_Button = new Button();          
          h.m_Button.Dock = DockStyle.Fill;
          h.m_Button.Margin = new Padding(0);
          h.m_Button.FlatStyle = FlatStyle.Popup;
        }
        h.m_Button.Parent = null;
        tableLayoutPanel1.Controls.Add(h.m_Button, 1 + ColN, 0);
        h.m_Button.Text = h.Caption;       
        ColN++;
      }
      tableLayoutPanel1.ColumnCount = 1 + ColN + 1;      

      RowN=0;
      foreach(IGrouping<IEnumerable<Object>,RowCollection.Row> gr in qGroup)
      {
        // Вывод группы
        GroupCollection.GroupeInfo gi = Group.getInfo(gr.Key);
        gi.Control.Parent = null;
        gi.Control.Dock = DockStyle.Fill;        
        tableLayoutPanel1.Controls.Add(gi.Control, 0, 1+RowN);
        tableLayoutPanel1.SetColumnSpan(gi.Control, 1 + ColN);
        tableLayoutPanel1.RowStyles.Add(gi.m_RowStyle);
        
        H += gi.Height;
        RowN++;

        foreach(RowCollection.Row row in gr)                
        {
          tableLayoutPanel1.RowStyles.Add(row.m_RowStyle);
          H += row.Height;
          if (row.m_Button==null)
          {
            row.m_Button = new Button();          
            row.m_Button.Dock = DockStyle.Fill;
            row.m_Button.Margin = new Padding(0);
            row.m_Button.FlatStyle = FlatStyle.Flat;          
            row.m_Button.Padding = new Padding(0);
          }
          row.m_Button.Parent = null;
          tableLayoutPanel1.Controls.Add(row.m_Button, 0, 1+RowN);
          row.m_Button.Text = (RowN+1).ToString();
  
          ColN=0;
          foreach(ColumnCollection.Column col in listHeader)
          {
            CellCollection.Cell cell = Cells.getCell(col,row);
            if (cell.m_Editor==null)
            {
               cell.m_Editor = createDeleate(cell);
               setDeleate(cell.m_Editor,cell);
            }
            cell.m_Editor.Parent = null;
            cell.m_Editor.Dock = DockStyle.Fill;
            tableLayoutPanel1.Controls.Add(cell.m_Editor,1+ColN ,1+RowN);
            //collection.Add(cell.m_Editor,1+ColN ,1+RowN);
            ColN++;   
          }
          RowN++;
        }
      }
/*
        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute,RowDefaultSize));                
        H += h.Height;
        rowN++; 
 */
      tableLayoutPanel1.RowCount = 1 + RowN + 1;
      tableLayoutPanel1.Width = (Int32)W;
      tableLayoutPanel1.Height = (Int32)H;      
      //showHeader(listHeader,listRow);
      //showCells(listHeader,listRow);
      //setCells();
    }
    readonly CellCollection Cells;
    public TableView()
    {
      Columns = new ColumnCollection(this);
      Rows = new RowCollection(this);
      Cells = new CellCollection(this);
      Group = new GroupCollection(this);
      DelegatorList = new List<Delegator>{new StandardDelegator()};
      //
      // The InitializeComponent() call is required for Windows Forms designer support.
      //
      InitializeComponent();
      //
      // TODO: Add constructor code after the InitializeComponent() call.
      //
    }
    void TableViewPaint(object sender, PaintEventArgs e)
    {
      Boolean s = m_Show;
      m_Show = true;
      if (s==false)
      {
        showAll();
      }      
    }
  }
}
